use std::collections::HashMap;

fn check_verify(id_card_no: &str) -> bool {
    let weights = [7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2];
    let check_codes = ['1', '0', 'X', '9', '8', '7', '6', '5', '4', '3', '2'];

    let mut sum = 0;
    for (i, c) in id_card_no.chars().take(17).enumerate() {
        if let Some(digit) = c.to_digit(10) {
            sum += digit * weights[i];
        } else {
            return false;
        }
    }

    let check_code = check_codes[(sum % 11) as usize];
    id_card_no.chars().last().unwrap_or(' ') == check_code
}

fn get_location(key: &str) -> String {
    let json = include_str!("./id.json");
    let map = serde_json::from_str::<HashMap<String, String>>(json).unwrap();
    if let Some(lo) = map.get(key) {
        return lo.to_string();
    } else {
        return "未知".to_string();
    }
}

pub fn check_id_card(id_card_no: &str) -> String { // 370725881105149
    if id_card_no.len() == 18 {
        if !check_verify(&id_card_no) {
            return "身份证号码错误".to_string();
        }
        let mut sex = "男".to_string();
        if id_card_no.get(16..17).unwrap().chars().last().unwrap().to_digit(10).unwrap() % 2 == 0 {
            sex = "女".to_string();
        }
        let location = get_location(id_card_no.get(0..6).unwrap());
        return format!("身份证号码正确,{},{}年{}月{}日,{}", sex, id_card_no.get(6..10).unwrap(), id_card_no.get(10..12).unwrap(), id_card_no.get(12..14).unwrap(), location);
    }
    if id_card_no.len() == 15 {
        let mut sex = "男".to_string();
        if id_card_no.chars().last().unwrap().to_digit(10).unwrap() % 2 == 0 {
            sex = "女".to_string();
        }
        let location = get_location(id_card_no.get(0..6).unwrap());
        return format!("身份证号码正确,{},19{}年{}月{}日,{}", sex, id_card_no.get(6..8).unwrap(), id_card_no.get(8..10).unwrap(), id_card_no.get(10..12).unwrap(), location);
    }
    "身份证号码错误".to_string()
}
